package main

import (
	"errors"
	"fmt"
	xerrors "github.com/pkg/errors"
	"golang.org/x/sync/errgroup"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
)

type httpListener struct {
	ln net.Listener
}

var hl httpListener

func main() {
	var g errgroup.Group

	g.Go(startHTTP)
	g.Go(signalHandle)

	log.Println("running......")
	if err := g.Wait(); err != nil {
		log.Println("from g.Wait():", err)
	}
}

func startHTTP() error {
	ln, err := net.Listen("tcp4", ":80")
	if nil != err {
		panic("from net.Listen:" + err.Error())
	}
	hl.ln = ln

	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "hello http")
	})

	if err = http.Serve(hl.ln, mux); err != nil {
		// 关闭的情况显示此提示更好看些：get signal, success exit
		if strings.Contains(err.Error(), "use of closed network connection") {
			return nil
		}
		return xerrors.Wrap(err, "from goServeHTTP()")
	}

	return nil
}

func signalHandle() error {
	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGINT)
	switch <-ch {
	case syscall.SIGTERM, syscall.SIGKILL, syscall.SIGINT:
		if err := hl.ln.Close(); err != nil {
			return xerrors.Wrap(err, "fail exit: err from hl.ln.Close()")
		}
	}

	return errors.New("get signal, success exit")
}
